package lib.base.http

import androidx.lifecycle.LifecycleCoroutineScope
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Job
import lib.base.note.PageStatusNote


/**
 *  author: luoXiong
 *  e-mail: 382060748@qq.com
 *  date: 2020/6/1 09:36
 *  version: 1.0
 *  desc:
 */
interface IReqCallback<ResponseType> {
    companion object {
        const val error_toast: Int = 1
        const val error_dialog = 2
        const val error_no_show = 3
    }


    // 接口成功回调
    open fun onSucceed(result: ResponseType) {

    }

    // 如果协程取消了, 也会抛出异常,如果在异常回调里获取Act来设置错误布局,会崩溃,因为Frag没有Act了
    open fun onErrorBefore(e: Throwable) {
        if (e !is CancellationException) {
            onError(e)
        }
    }

    // 接口失败回调
    open fun onError(e: Throwable) {

    }

    //接口完成回调, 无论失败和成功都会执行
    open fun onComplete() {

    }
    //var api: (suspend () -> ResponseType)? = null

    @PageStatusNote
    fun getShowPageStatus(): Int {
        return PageStatusNote.def_loading
    }

    /**
     * 如果发生错误,是否通过吐司弹出
     * 返回类型参考: IReqCallback
     */
    open fun getShowErrorUIWay(): Int {
        return IReqCallback.error_no_show
    }

    // 是否显示加载中的对话筐
    fun isShowLoadingDialog(): Boolean {
        return true
    }

    // dialog 加载筐的文本
    fun getDialogLoadingText(): String? {
        return null
    }

}

abstract class Req<ResponseType> : IReqCallback<ResponseType> {
    constructor(api: (suspend () -> ResponseType)) {
        this.api = api
    }

    constructor(scope: LifecycleCoroutineScope? = null) {
        this._scope = scope
    }

    private var _scope: LifecycleCoroutineScope? = null
    private var _lastJob: Job? = null
    private lateinit var api: (suspend () -> ResponseType)

    open fun getApi(): suspend () -> ResponseType {
        return api
    }

    fun getScope(): LifecycleCoroutineScope? {
        return _scope
    }


    //    var api: (suspend () -> ResponseType)? = null
    fun setApi(block: suspend () -> ResponseType): Req<ResponseType> {
        this.api = block
        return this
    }

    fun setJob(job: Job) {
        _lastJob = job
        onJobCreated(job)
    }

    open fun onJobCreated(job: Job) {

    }

    fun getLastReq(): Job? {
        return _lastJob
    }
}